/*

 Copyright (c) 2008-2009 Fabrizio Pistonesi

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 */

#include "sound.h"
Sound::Sound(){};

Sound::Sound(AudioDevicePtr audiodev, ICameraSceneNode *handler, stringc source, bool autostart,
    bool repeat, float volume, float pan, float pitch, f32 az, f32 el)
  {
    AudioDev = audiodev;
    Source = source; //serialize
    Autostart = autostart;

    Pointer = handler;

    Stream = OpenSound(AudioDev, Source.c_str(), true);
    if (!Stream)
      {
        // failure
        printf("Sound stream error: %s.\n", Source.c_str());
      }
    else
    {
      printf("Sound stream loaded: %s.\n", Source.c_str());
      Stream->setRepeat(repeat);
      Stream->setVolume(volume);
      Stream->setPan(pan);
      Stream->setPitchShift(pitch);
      if (autostart)Stream->play();
    }

    Azimuth = az;
    Elevation = el;
    Volume = volume;
  }

Sound::~Sound()
  {
    if(Stream)Stream->stop();
  }

void Sound::play()
  {
    Stream->play();
  }

bool Sound::isPlaying()
  {
    return Stream->isPlaying();
  }

void Sound::stop()
  {
    Stream->stop();
  }

void Sound::setRepeat(bool repeat)
  {
    Stream->setRepeat(repeat);
  }

void Sound::setVolume(float volume)
  {
    Stream->setVolume(volume);
  }

void Sound::setPan(float pan)
  {
    Stream->setPan(pan);
  }

void Sound::setPitch(float pitch)
  {
    Stream->setPitchShift(pitch);
  }

void Sound::setPosition(f32 az, f32 el)
  {
    Azimuth = az;
    Elevation = el;
  }

void Sound::update()
  {
    float pan, volume, az, el;
    az = Azimuth - Pointer->getRotation().Y/57.5f;
    el = Elevation- Pointer->getRotation().X/57.5f;
    pan = sin(az);
    //volume = (cos(az)+1.25)/2; // 1.25 instead 1 don't let the volume get 0 when facing oppose the source
    //volume = volume * ((1-(cos(el)+1))/2);
    volume = cos(el) * (cos(az)+1.1)/2;
    if(Stream)
      {
        Stream->setPan(pan);
        Stream->setVolume(Volume * volume);
      }
  }

void Sound::serialize(IAttributes* attributes)
  {
    attributes->addString("source", Source.c_str());
    attributes->addFloat("azimuth",Azimuth);
    attributes->addFloat("elevation",Elevation);
    attributes->addFloat("volume",Volume);
    attributes->addFloat("pan",Stream->getPan());
    attributes->addFloat("pitch",Stream->getPitchShift());
    attributes->addBool("repeat",Stream->getRepeat());
    attributes->addBool("autostart", Autostart);
  }
